package com.xm.eboot.generator;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Test;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName: CodeGenerator
 * @Description: MyBatisPlus代码生成器
 * @author mengxc
 * @date 2021年7月1日 上午9:43:06
 */
@Slf4j
public class CodeGenerator {

	/********************* 公共字段配置-start ****************************/
	// 自定义需要填充的字段 使用MetaObjectHandlerConfig.java全局配置配合使用
	private static List<TableFill> TABLE_FILL_LIST = new ArrayList<TableFill>();
	static {
		// 创建时间
		TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
		TABLE_FILL_LIST.add(createTime);

		// 修改时间
		TableFill updateTime = new TableFill("update_time", FieldFill.INSERT_UPDATE);
		TABLE_FILL_LIST.add(updateTime);

		// 创建人
		TableFill createBy = new TableFill("create_by", FieldFill.INSERT);
		TABLE_FILL_LIST.add(createBy);

		// 修改人
		TableFill updateBy = new TableFill("update_by", FieldFill.INSERT_UPDATE);
		TABLE_FILL_LIST.add(updateBy);
	}
	/********************* 公共字段配置-end ****************************/

	// 全局配置
	private static final String OUTPUT_DIR = "D:/code";// 示例:D:/code,
														// 如果使用System.getProperty("user.dir")则直接生成在项目路径下(慎用，可能会覆盖原代码);
	private static final String AUTHOR = "mengxc";// 作者
	private static final boolean SWAGGER2 = true;// 是否开启Swagger
	private static final boolean FILE_OVERRIDE = false;// 是否覆盖原文件

	// 数据源配置
	private static final String URL = "jdbc:mysql://39.98.165.231:3306/fd_cloud?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true&characterEncoding=UTF-8";// 数据源URL
	private static final String DRIVER_NAME = "com.mysql.cj.jdbc.Driver";// 数据源驱动
	private static final String USERNAME = "root";// 数据源用户名
	private static final String PASSWORD = "uat@2019";// 数据源密码

	// 包配置
	private static final String MODULE_NAME = "";// 子模块名
	private static final String PARENT = "cn.com.xuanjifen.minsheng.tmall.rightinterests";// 包名

	// 策略配置
	private static final String[] INCLUDE = { "marketing_activities_ms_sk_pv", "marketing_activities_ms_sk_uv",
			"marketing_activities_ms_web_pv", "marketing_activities_ms_web_uv" };// 需要生成的表
	private static final String[] TABLE_PREFIX = {};// 需要去除的表前缀，例如:{ "sys_" }
	private static final boolean REST_CONTROLLER_STYLE = true;// 是否使用RestFull风格接口
	private static final boolean LOMBOK = false;// 是否使用Lombok

	@Test
	public void doGenerator() {
		log.info("==>欢迎使用EBoot代码生成器");
		log.info("代码输出路径:{}", OUTPUT_DIR);
		log.info("作者:{}", AUTHOR);
		log.info("Swagger2:{}", SWAGGER2 ? "开启" : "关闭");
		log.info("是否覆盖原文件:{}", FILE_OVERRIDE ? "是" : "否");
		log.info("数据源URL:{}", URL);
		log.info("数据源驱动:{}", DRIVER_NAME);
		log.info("数据源用户名:{}", USERNAME);
		log.info("数据源密码:{}", PASSWORD);
		log.info("模块名:{}", MODULE_NAME);
		log.info("包名:{}", PARENT);
		log.info("需要生成的表:{}", StringUtils.join(INCLUDE, ","));
		log.info("忽略表前缀:{}", StringUtils.join(TABLE_PREFIX, ","));
		log.info("RestFull风格:{}", REST_CONTROLLER_STYLE ? "开启" : "关闭");
		log.info("Lombok支持:{}", LOMBOK ? "开启" : "关闭");

		log.info("==>代码生成中...");
		// 代码生成器
		AutoGenerator mpg = new AutoGenerator();
		// 全局配置
		GlobalConfig gc = new GlobalConfig();
		gc.setOutputDir(OUTPUT_DIR + "/src/main/java");
		gc.setAuthor(AUTHOR);
		gc.setOpen(false);
		gc.setSwagger2(SWAGGER2);
		gc.setServiceName("%sService"); // 去掉Service接口的首字母I
		gc.setFileOverride(FILE_OVERRIDE);
		gc.setDateType(DateType.ONLY_DATE);// 时间类型
//		gc.setEnableCache(false);// XML 二级缓存
//        gc.setBaseResultMap(true);// XML ResultMap
//        gc.setBaseColumnList(true);// XML columList
//        gc.setKotlin(true); //是否生成 kotlin 代码
		mpg.setGlobalConfig(gc);

		// 数据源配置
		DataSourceConfig dsc = new DataSourceConfig();
		dsc.setUrl(URL);
		dsc.setDriverName(DRIVER_NAME);
		dsc.setUsername(USERNAME);
		dsc.setPassword(PASSWORD);
		mpg.setDataSource(dsc);

		// 包配置
		PackageConfig pc = new PackageConfig();
		pc.setModuleName(MODULE_NAME);
		pc.setParent(PARENT);
		pc.setController("controller");
		pc.setEntity("entity");
		pc.setService("service");
		pc.setMapper("dao");
//		pc.setXml("mapper");
		mpg.setPackageInfo(pc);

		// 模板配置(可以自定义模板)
		TemplateConfig templateConfig = new TemplateConfig();
//		templateConfig.setController("templates/controller.java");
//		templateConfig.setEntity("templates/entity.java");
//		templateConfig.setMapper("templates/mapper.java");
//		templateConfig.setService("templates/service.java");
//		templateConfig.setServiceImpl("templates/serviceImpl.java");
		templateConfig.setXml(null);// 不需要生成xml,xml在下面重新定义目录生成
		mpg.setTemplate(templateConfig);

		// 自定义配置
		InjectionConfig cfg = new InjectionConfig() {
			@Override
			public void initMap() {
				// to do nothing
			}
		};
		// 如果模板引擎是 freemarker
		String templatePath = "/templates/mapper.xml.ftl";
		// 自定义输出配置
		List<FileOutConfig> focList = new ArrayList<>();
		// 自定义配置会被优先输出
		focList.add(new FileOutConfig(templatePath) {
			@Override
			public String outputFile(TableInfo tableInfo) {
				// 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
				return OUTPUT_DIR + "/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper"
						+ StringPool.DOT_XML;
			}
		});

		cfg.setFileOutConfigList(focList);
		mpg.setCfg(cfg);

		// 策略配置
		StrategyConfig strategy = new StrategyConfig();
		strategy.setNaming(NamingStrategy.underline_to_camel);// 名称下换线转驼峰
		strategy.setColumnNaming(NamingStrategy.underline_to_camel);// 字段名称下换线转驼峰
		strategy.setEntityLombokModel(LOMBOK);// 使用Lombok
		strategy.setRestControllerStyle(REST_CONTROLLER_STYLE);// 使用RestController
		strategy.setInclude(INCLUDE);
		strategy.setControllerMappingHyphenStyle(true);// RequestMapping路径格式：如表名为：ups_info,设置false -> upsInfo，设置true -> ups-info 
		strategy.setTablePrefix(TABLE_PREFIX);
		strategy.setTableFillList(TABLE_FILL_LIST);
		strategy.setEntityBooleanColumnRemoveIsPrefix(true);// Boolean类型字段是否移除is前缀
		mpg.setStrategy(strategy);
		mpg.setTemplateEngine(new FreemarkerTemplateEngine());
		mpg.execute();
		log.info("==>代码生成完成!");
	}
}
